from django import forms
from django.forms.widgets import Widget
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string
from content.models import Category

class CollapsibleCategoryWidget(Widget):
    """
    可折叠分类选择控件，支持搜索过滤和已选分类标签显示
    """
    
    def __init__(self, attrs=None, choices=()):
        super().__init__(attrs)

    def render(self, name, value, attrs=None, renderer=None):
        if value is None:
            value = []
        
        # 如果value不是列表，转换为列表
        if not isinstance(value, (list, tuple)):
            value = [value] if value else []
        
        # 获取所有分类并构建树形结构
        categories = Category.objects.all()
        category_dict = {cat.id: cat for cat in categories}
        
        # 构建分类树
        tree = self._build_tree(categories)
        
        # 生成根分类（第一层默认展开）
        tree_html = self._generate_tree_html(tree, category_dict, name, value, parent_id=0)
        
        # 准备模板上下文
        context = {
            'name': name,
            'tree_html': tree_html,
        }
        
        # 渲染模板
        html = render_to_string('custom_admin/widgets/collapsible_category_widget.html', context)
        
        return mark_safe(html)
    
    def _build_tree(self, categories):
        """
        构建分类树结构
        """
        tree = {}
        for category in categories:
            if category.parent_id:
                if category.parent_id not in tree:
                    tree[category.parent_id] = []
                tree[category.parent_id].append(category.id)
            else:
                if 0 not in tree:
                    tree[0] = []
                tree[0].append(category.id)
        return tree
    
    def _generate_tree_html(self, tree, category_dict, name, selected_values, parent_id=0, level=0):
        """
        生成树形HTML结构
        """
        html = ''
        if parent_id in tree:
            for category_id in tree[parent_id]:
                category = category_dict[category_id]
                has_children = category_id in tree and len(tree[category_id]) > 0
                # 确保selected_values中的值是整数类型
                selected_ids = []
                for v in selected_values:
                    try:
                        selected_ids.append(int(v))
                    except (ValueError, TypeError):
                        pass
                checked = 'checked' if category_id in selected_ids else ''
                indent = '&nbsp;&nbsp;&nbsp;&nbsp;' * level
                
                # 添加树形连接线
                if level > 0:
                    tree_line = '|— '
                else:
                    tree_line = ''
                
                html += f'''
                <div class="category-item" data-id="{category_id}" data-parent="{parent_id}" style="padding: 2px 0; font-size: 0.9rem;">
                '''
                
                # 添加展开/折叠按钮（如果有子分类）
                if has_children:
                    html += f'''
                    <span id="toggle-{category_id}" class="category-toggle" onclick="toggleCategoryChildren({category_id})" style="cursor: pointer; margin-right: 5px;">+</span>
                    '''
                else:
                    html += '''
                    <span style="margin-right: 5px; visibility: hidden;">+</span>
                    '''
                
                # 添加缩进和连接线
                html += f'''
                    {indent}{tree_line}
                    <input class="form-check-input" type="checkbox" name="{name}" value="{category_id}" 
                           id="id_{name}_{category_id}" {checked} onchange="handleCategoryChange(this)">
                    <label class="category-label" for="id_{name}_{category_id}" style="margin-left: 2px;">
                        {category.name}
                    </label>
                '''
                
                html += '''
                </div>
                '''
                
                # 如果有子分类，添加子分类容器
                if has_children:
                    display_style = 'block' if level == 0 else 'none'  # 第一层默认展开，其他层默认折叠
                    html += f'''
                    <div id="children-{category_id}" class="category-children" style="display: {display_style}; margin-left: 20px;">
                    '''
                    html += self._generate_tree_html(
                        tree, category_dict, name, selected_values, category_id, level + 1
                    )
                    html += '''
                    </div>
                    '''
        
        return html
    
    def value_from_datadict(self, data, files, name):
        """
        从表单数据中获取值
        """
        return data.getlist(name)


class ModalCategoryWidget(Widget):
    """
    模态框分类选择控件，避免占用过多表单空间
    """
    
    def __init__(self, attrs=None, choices=()):
        super().__init__(attrs)

    def render(self, name, value, attrs=None, renderer=None):
        if value is None:
            value = []
        
        # 如果value不是列表，转换为列表
        if not isinstance(value, (list, tuple)):
            value = [value] if value else []
        
        # 获取所有分类
        categories = Category.objects.all()
        category_dict = {cat.id: cat for cat in categories}
        
        # 构建分类树
        tree = self._build_tree(categories)
        
        # 生成根分类（第一层默认展开）
        tree_html = self._generate_tree_html(tree, category_dict, name, value, parent_id=0)
        
        # 生成隐藏的input字段
        hidden_inputs = ''.join(f'<input type="hidden" name="{name}" value="{val}">' for val in value)
        
        # 准备模板上下文
        context = {
            'name': name,
            'tree_html': tree_html,
            'hidden_inputs': hidden_inputs,
        }
        
        # 渲染模板
        html = render_to_string('custom_admin/widgets/modal_category_widget.html', context)
        
        return mark_safe(html)
    
    def _build_tree(self, categories):
        """
        构建分类树结构
        """
        tree = {}
        for category in categories:
            if category.parent_id:
                if category.parent_id not in tree:
                    tree[category.parent_id] = []
                tree[category.parent_id].append(category.id)
            else:
                if 0 not in tree:
                    tree[0] = []
                tree[0].append(category.id)
        return tree
    
    def _generate_tree_html(self, tree, category_dict, name, selected_values, parent_id=0, level=0):
        """
        生成树形HTML结构
        """
        html = ''
        if parent_id in tree:
            for category_id in tree[parent_id]:
                category = category_dict[category_id]
                has_children = category_id in tree and len(tree[category_id]) > 0
                # 确保selected_values中的值是整数类型
                selected_ids = []
                for v in selected_values:
                    try:
                        selected_ids.append(int(v))
                    except (ValueError, TypeError):
                        pass
                checked = 'checked' if category_id in selected_ids else ''
                indent = '&nbsp;&nbsp;&nbsp;&nbsp;' * level
                
                # 添加树形连接线
                if level > 0:
                    tree_line = '|— '
                else:
                    tree_line = ''
                
                html += f'''
                <div class="category-item" data-id="{category_id}" data-parent="{parent_id}" style="padding: 2px 0; font-size: 0.9rem;">
                '''
                
                # 添加展开/折叠按钮（如果有子分类）
                if has_children:
                    html += f'''
                    <span id="toggle-{name}-{category_id}" class="category-toggle" onclick="toggleCategoryChildren('{name}', {category_id})" style="cursor: pointer; margin-right: 5px;">+</span>
                    '''
                else:
                    html += f'''
                    <span style="margin-right: 5px; visibility: hidden;">+</span>
                    '''
                
                # 添加缩进和连接线
                html += f'''
                    {indent}{tree_line}
                    <input class="form-check-input" type="checkbox" name="modal-{name}" value="{category_id}" 
                           id="id_modal_{name}_{category_id}" {checked}>
                    <label class="category-label" for="id_modal_{name}_{category_id}" style="margin-left: 2px;">
                        {category.name}
                    </label>
                '''
                
                html += '''
                </div>
                '''
                
                # 如果有子分类，添加子分类容器
                if has_children:
                    display_style = 'block' if level == 0 else 'none'  # 第一层默认展开，其他层默认折叠
                    html += f'''
                    <div id="children-{name}-{category_id}" class="category-children" style="display: {display_style}; margin-left: 20px;">
                    '''
                    html += self._generate_tree_html(
                        tree, category_dict, name, selected_values, category_id, level + 1
                    )
                    html += '''
                    </div>
                    '''
        
        return html
    
    def value_from_datadict(self, data, files, name):
        """
        从表单数据中获取值
        """
        return data.getlist(name)